#include "filegenerator.h"
#include <shapefil.h>
#include <fstream>
#include <ctime>
#include <wx/dir.h>

//基金业务类型
#define REDEEM_TYPE             "112"
#define FORCED_REDEEM_TYPE      "342"
#define RODUNS_TYPE             "343"
#define WINDING_TYPE            "350"
#define SUBSCRIPTION            "110"
#define PURCHASE                "111"
#define REGULAR_PURCHASE        "115"
#define FAILED_TO_RAISE         "349"

wxDEFINE_EVENT(wxEVENT_COMMAND_MYHANDER_SUCCESS,wxThreadEvent);
wxDEFINE_EVENT(wxEVENT_COMMAND_MYHANDER_FAIL,wxThreadEvent);


fileGenerator::fileGenerator(mainFrame * hander) : wxThread(wxTHREAD_DETACHED)
{

}

fileGenerator::~fileGenerator()
{

}

wxThread::ExitCode fileGenerator::Entry()
{
    if (m_pFunds == nullptr)
    {
        wxQueueEvent(m_Hander, new wxThreadEvent(wxEVENT_COMMAND_MYHANDER_FAIL));
        return (wxThread::ExitCode)-1;
    }
    if (generateCsv() && generateDbf())
    {
        wxQueueEvent(m_Hander, new wxThreadEvent(wxEVENT_COMMAND_MYHANDER_SUCCESS));
    }
    else
    {
        wxQueueEvent(m_Hander, new wxThreadEvent(wxEVENT_COMMAND_MYHANDER_FAIL));
    }
    return (wxThread::ExitCode)0;
}

void fileGenerator::setFundsPonit(std::vector<Fund> *ponit)
{
    if (ponit == nullptr)
        return;
    m_pFunds = ponit;
}

bool fileGenerator::generateDbf()
{
    wxString fileName = wxT("./out/fundinfo.dbf");


    if (!wxDir::Exists(wxT("./out")))
    {
        wxDir::Make(wxT("./out"));
    }

    #ifdef OUT_FILE_COVER
    
    当导出文件已经存在时，不覆盖，通过增加文件数字后缀的方式重命名
    if (wxFile::Exists(fileName))
    {
    	int fileNum = 1;
    	while (wxFile::Exists(fileName))
    	{
    		fileName = wxString::Format(wxT("./out/fundinfo_%i.dbf"), fileNum++);
    	}
    }
    
   #endif

    //创建DBF
    auto dbfhandle = DBFCreate(fileName.ToStdString().c_str());

    //检查创建情况
    if (dbfhandle == NULL)
    {
        //wxMessageBox(wxT("新意文件导出失败，创建DBF文件句柄失败"),wxT("错误信息"),wxOK | wxICON_ERROR);
        return false;
    }

    //添加字段
    DBFAddField(dbfhandle, "MODEL_ID", FTString, 10, 0);
    DBFAddField(dbfhandle, "FUND_CODE", FTString, 30, 0);
    DBFAddField(dbfhandle, "FUND_NAME", FTString, 40, 0);
    DBFAddField(dbfhandle, "TA_CODE", FTString, 6, 0);
    DBFAddField(dbfhandle, "CUR_TYPE", FTString, 3, 0);
    DBFAddField(dbfhandle, "IS_CHARGE", FTString, 1, 0);
    DBFAddField(dbfhandle, "FUND_STYLE", FTString, 1, 0);
    DBFAddField(dbfhandle, "FULL_NAME", FTString, 60, 0);
    DBFAddField(dbfhandle, "TA_PUBLISH", FTString, 30, 0);
    DBFAddField(dbfhandle, "DATE_BEG", FTString, 8, 0);
    DBFAddField(dbfhandle, "DATE_END", FTString, 8, 0);
    DBFAddField(dbfhandle, "SETTLEBANK", FTString, 30, 0);
    DBFAddField(dbfhandle, "NOTE", FTString, 255, 0);
    DBFAddField(dbfhandle, "TRADEPLACE", FTString, 1, 0);
    DBFAddField(dbfhandle, "FIRST_DATE", FTString, 8, 0);
    DBFAddField(dbfhandle, "MAIN_FUND", FTString, 30, 0);

    wxString current_date_str = wxDateTime::Now().Format("%Y%m%d");

    //增加记录
    for (size_t i = 0; i < m_pFunds->size(); i++)
    {
        DBFWriteStringAttribute(dbfhandle, i, 0, (*m_pFunds)[i].parse_id);
        DBFWriteStringAttribute(dbfhandle, i, 1, (*m_pFunds)[i].fund_code);
        DBFWriteStringAttribute(dbfhandle, i, 2, (*m_pFunds)[i].fund_name);
        DBFWriteStringAttribute(dbfhandle, i, 3, (*m_pFunds)[i].ta_code);
        DBFWriteStringAttribute(dbfhandle, i, 4, "CNY");
        DBFWriteStringAttribute(dbfhandle, i, 5, "0");
        DBFWriteStringAttribute(dbfhandle, i, 6, "0");
        DBFWriteStringAttribute(dbfhandle, i, 7, (*m_pFunds)[i].fund_name);
        DBFWriteNULLAttribute(dbfhandle, i, 8);
        DBFWriteStringAttribute(dbfhandle, i, 9, current_date_str.ToStdString().c_str());
        DBFWriteStringAttribute(dbfhandle, i, 10, current_date_str.ToStdString().c_str());
    }
    //关闭
    DBFClose(dbfhandle);

    //拷贝文件进行备份，文件以日期和时间为后缀
    if (!wxDir::Exists(wxT("./bak")))
    {
        wxDir::Make(wxT("./bak"));
    }

    //备份文件
    char timeStr[128];
    time_t currentTime = time(NULL);
    strftime(timeStr,128,"%Y-%m-%d-%H-%M-%S",localtime(&currentTime));     
    wxCopyFile(fileName,wxString(wxT("./bak/fundinfo_")).append(timeStr).append(wxT(".dbf")),true);
    return true;
}
bool fileGenerator::generateCsv()
{
    wxString fileName = wxT("./out/fundinfo.csv");
    std::string  csvFileName = "./out/fundinfo.csv";

    if (!wxDir::Exists(wxT("./out")))
    {
        wxDir::Make(wxT("./out"));
    }
    std::ofstream outFile;
    outFile.open("./out/fundinfo.csv", std::ios::out);
    if (outFile.fail())
    {
        //wxMessageBox(wxT("OTC文件导出失败\n\n fundinfo.csv文件打开失败"),wxT("CSV文件导出"), wxOK | wxICON_ERROR);
        return false;
    }
    outFile << "产品编码" << ",";
    outFile << "交易类别" << ",";
    outFile << "清算方式" << ",";
    outFile << "DVP交收标志" << ",";
    outFile << "担保交收标志" << ",";
    outFile << "资金交收天数" << ",";
    outFile << "份额交收天数" << ",";
    outFile << "资金可用天数" << ",";
    outFile << "份额可用天数" << ",";
    outFile << "结算币种" << ",";
    outFile << "清算模式" << ",";
    outFile << "资金交收标志" << ",";
    outFile << "赎回资金处理方式" << ",";
    outFile << std::endl;

    for (const auto &item : (*m_pFunds))
    {
        //增加赎回
        outFile << "\t" << item.fund_code << ",";
        outFile << "\t" << REDEEM_TYPE << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << item.otc_sh_date << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << item.otc_sh_date << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "2" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "0" << "," << std::endl;

        //增加强赎
        outFile << "\t" << item.fund_code << ",";
        outFile << "\t" << FORCED_REDEEM_TYPE << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << item.otc_sh_date << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << item.otc_sh_date << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "2" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "0" << "," << std::endl;

        //增加清盘
        outFile << "\t" << item.fund_code << ",";
        outFile << "\t" << WINDING_TYPE << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << item.otc_sh_date << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << item.otc_sh_date << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "2" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "0" << "," << std::endl;

        //增加分红
        outFile << "\t" << item.fund_code << ",";
        outFile << "\t" << RODUNS_TYPE << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << item.otc_fh_date << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << item.otc_fh_date << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "2" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "0" << "," << std::endl;

         //增加认购
        outFile << "\t" << item.fund_code << ",";
        outFile << "\t" << SUBSCRIPTION << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "1" << ",";
        outFile << "\t" << "0" << ",";
        outFile << "\t" << "0" << ",";
        outFile << std::endl;

        //设置申购
        outFile << "\t" << item.fund_code <<",";
        outFile << "\t" << PURCHASE <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "0" <<",";
        outFile << std::endl;

        //设置定时定额申购
        outFile << "\t" << item.fund_code <<",";
        outFile << "\t" << REGULAR_PURCHASE <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "0" <<",";
        outFile << std::endl;

        //设置募集失败
        outFile << "\t" << item.fund_code <<",";
        outFile << "\t" << FAILED_TO_RAISE <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "2" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "2" <<",";
        outFile << "\t" << "1" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "2" <<",";
        outFile << "\t" << "0" <<",";
        outFile << "\t" << "0" <<",";
        outFile << std::endl;

    }
    outFile.close();

    // 拷贝文件进行备份，文件以日期和时间为后缀
    if (!wxDir::Exists(wxT("./bak")))
    {
        wxDir::Make(wxT("./bak"));
    }

    // 增加备份文件
    char timeStr[128];
    time_t currentTime = time(NULL);
    strftime(timeStr, 128, "%Y-%m-%d-%H-%M-%S", localtime(&currentTime));
    wxCopyFile(fileName, wxString("./bak/fundinfo_").append(timeStr).append(".csv"), true);

    return true;
}